/*
 * Copyright (c) 2008 Benoit Bouchez, Nicolas Giard
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.noocodecommit.wicket.stuff.jquery.core;

import org.apache.wicket.Component;

/**
 * JQSelectorBuilder helps you to create JQuery selectors *
 * 
 * @author Benoit Bouchez
 */
public class JQSelectorBuilder
{

	/**
	 * Matches all elements.<br>
	 * Most useful when combined with a context to search in.
	 * 
	 * @return
	 */
	public static JQSelector all()
	{
		return new JQSelector("*");
	}

	/**
	 * Matches all elements with the given class.
	 * 
	 * @param cssClass
	 *            css class name
	 * @return
	 */
	public static JQSelector cssClass(String cssClass)
	{
		return new JQSelector("." + cssClass);
	}

	/**
	 * Matches all elements with the given name.
	 * 
	 * @param element
	 *            element name
	 * @return
	 */
	public static JQSelector element(String element)
	{
		return new JQSelector(element);
	}

	/**
	 * Matches a single element with the given id attribute.<br>
	 * If the id contains characters like periods or colons you have to escape those characters with backslashes
	 * 
	 * @param id
	 *            element id
	 * @return
	 */
	public static JQSelector id(String id)
	{
		return new JQSelector("#" + id);
	}

	/**
	 * Matches a single element with the given id attribute.<br>
	 * If the id contains characters like periods or colons you have to escape those characters with backslashes
	 * 
	 * @param component
	 *            wicket component
	 * @return
	 */
	public static JQSelector id(Component component)
	{
		return new JQSelector("#" + component.getMarkupId());
	}

	/**
	 * Matches the combined results of all the specified selectors.<br>
	 * You can specify any number of selectors to combine into a single result
	 * 
	 * @param selectors
	 *            array of selectors
	 * @return
	 */
	public static JQSelector multiple(JQSelector[] selectors)
	{
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < selectors.length; i++)
		{
			if (i == selectors.length - 1)
			{
				sb.append(selectors[i]);
			}
			else
			{
				sb.append(selectors[i] + ", ");
			}
		}
		return new JQSelector(sb.toString());
	}

	/**
	 * Matches the combined results of all the specified selectors.<br>
	 * You can specify any number of selectors to combine into a single result
	 * 
	 * @param selectors
	 *            array of selectors
	 * @return
	 */
	public static JQSelector multiple(String[] selectors)
	{
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < selectors.length; i++)
		{
			if (i == selectors.length - 1)
			{
				sb.append(selectors[i]);
			}
			else
			{
				sb.append(selectors[i] + ", ");
			}
		}
		return new JQSelector(sb.toString());
	}

	/**
	 * Matches all child elements specified by "child" of elements specified by "parent".
	 * 
	 * @param parent
	 *            parent selector
	 * @param child
	 *            child selector
	 * @return
	 */
	public static JQSelector child(JQSelector parent, JQSelector child)
	{
		return new JQSelector(parent + " > " + child);
	}

	/**
	 * Matches all child elements specified by "child" of elements specified by "parent".
	 * 
	 * @param parent
	 *            parent selector
	 * @param child
	 *            child selector
	 * @return
	 */
	public static JQSelector child(String parent, String child)
	{
		return new JQSelector(parent + " > " + child);
	}

	/**
	 * Matches all descendant elements specified by "descendant" of elements specified by "ancestor".
	 * 
	 * @param ancestor
	 *            ancestor selector
	 * @param descendant
	 *            descendant selector
	 * @return
	 */
	public static JQSelector descendant(JQSelector ancestor, JQSelector descendant)
	{
		return new JQSelector(ancestor + " " + descendant);
	}

	/**
	 * Matches all descendant elements specified by "descendant" of elements specified by "ancestor".
	 * 
	 * @param ancestor
	 *            ancestor selector
	 * @param descendant
	 *            descendant selector
	 * @return
	 */
	public static JQSelector descendant(String ancestor, String descendant)
	{
		return new JQSelector(ancestor + " " + descendant);
	}

	/**
	 * Matches all next elements specified by "next" that are next to elements specified by "prev".
	 * 
	 * @param prev
	 *            previous selector
	 * @param next
	 *            next selector
	 * @return
	 */
	public static JQSelector next(JQSelector prev, JQSelector next)
	{
		return new JQSelector(prev + " + " + next);
	}

	/**
	 * Matches all next elements specified by "next" that are next to elements specified by "prev".
	 * 
	 * @param prev
	 *            previous selector
	 * @param next
	 *            next selector
	 * @return
	 */
	public static JQSelector next(String prev, String next)
	{
		return new JQSelector(prev + " + " + next);
	}

	/**
	 * Matches all sibling elements after the "prev" element that match the filtering "siblings" selector.
	 * 
	 * @param prev
	 *            previous selector
	 * @param siblings
	 *            siblings selector
	 * @return
	 */
	public static JQSelector siblings(JQSelector prev, JQSelector siblings)
	{
		return new JQSelector(prev + " ~ " + siblings);
	}

	/**
	 * Matches all sibling elements after the "prev" element that match the filtering "siblings" selector.
	 * 
	 * @param prev
	 *            previous selector
	 * @param siblings
	 *            siblings selector
	 * @return
	 */
	public static JQSelector siblings(String prev, String siblings)
	{
		return new JQSelector(prev + " ~ " + siblings);
	}
	
	/**
	 * Matches all input elements of type button.
	 * 
	 * @return
	 */
	public static JQSelector button()
	{
		return new JQSelector(":button");
	}

	/**
	 * Matches all input elements of type checkbox.
	 * 
	 * @return
	 */
	public static JQSelector checkbox()
	{
		return new JQSelector(":checkbox");
	}

	/**
	 * Matches all input elements of type file.
	 * 
	 * @return
	 */
	public static JQSelector file()
	{
		return new JQSelector(":file");
	}

	/**
	 * Matches all elements that are hidden, or input elements of type "hidden".
	 * 
	 * @return
	 */
	public static JQSelector hidden()
	{
		return new JQSelector(":hidden");
	}

	/**
	 * Matches all input elements of type image.
	 * 
	 * @return
	 */
	public static JQSelector image()
	{
		return new JQSelector(":image");
	}

	/**
	 * Matches all input, textarea, select and button elements.
	 * 
	 * @return
	 */
	public static JQSelector input()
	{
		return new JQSelector(":input");
	}

	/**
	 * Matches all input elements of type password.
	 * 
	 * @return
	 */
	public static JQSelector password()
	{
		return new JQSelector(":password");
	}

	/**
	 * Matches all input elements of type radio.
	 * 
	 * @return
	 */
	public static JQSelector radio()
	{
		return new JQSelector(":radio");
	}

	/**
	 * Matches all input elements of type reset.
	 * 
	 * @return
	 */
	public static JQSelector reset()
	{
		return new JQSelector(":submit");
	}

	/**
	 * Matches all input elements of type text.
	 * 
	 * @return
	 */
	public static JQSelector text()
	{
		return new JQSelector(":text");
	}

}
